import React, { useState, useEffect, useRef } from "react";

interface AnimatedNumberProps {
    value: number;
    duration?: number; // 动画持续时间（毫秒）
    className?: string; // 自定义类名
    formatter?: (rawValue: number) => string; // 自定义格式化函数
}

// 为整数部分添加逗号分隔，小数部分完全保留
const formatWithCommas = (num: number): string => {
    // 特殊情况处理
    if (!isFinite(num)) return String(num);
    // 将数字转换为字符串
    const numStr = num.toString();
    // 分离整数和小数部分
    const parts = numStr.split(".");
    // 处理整数部分（包括负号）
    let integerPart = parts[0];
    let sign = "";
    // 处理负数
    if (integerPart.startsWith("-")) {
        sign = "-";
        integerPart = integerPart.slice(1);
    }
    // 为整数部分添加逗号
    integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    // 组合完整字符串
    let result = sign + integerPart;
    if (parts.length > 1) {
        result += "." + parts[1];
    }
    return result;
};
const AnimatedNumber: React.FC<AnimatedNumberProps> = ({
    value,
    duration = 2000,
    className = "",
    formatter = formatWithCommas, // 使用自定义格式化作为默认
}) => {
    const [displayValue, setDisplayValue] = useState<number>(value);
    const startTime = useRef<number | null>(null);
    const prevValue = useRef<number>(value);
    const animationFrameId = useRef<number>(0);

    useEffect(() => {
        // 清除任何进行的动画
        if (animationFrameId.current) {
            cancelAnimationFrame(animationFrameId.current);
        }
        const partsLength = value.toString().split(".")[1]?.length;
        prevValue.current = displayValue;
        startTime.current = null;
        const animate = (timestamp: number) => {
        if (!startTime.current) startTime.current = timestamp;
        const elapsed = timestamp - startTime.current;
        const progress = Math.min(elapsed / duration, 1);
        // 使用缓动函数使动画更自然
        const easeProgress = progress < 0.5 ? 2 * progress * progress : 1 - Math.pow(-2 * progress + 2, 2) / 2;
        // 计算当前动画值
        const currentValue = (
            prevValue.current +
            (value - prevValue.current) * easeProgress
        ).toFixed(partsLength);
            setDisplayValue(Number(currentValue));
            if (progress < 1) {
                animationFrameId.current = requestAnimationFrame(animate);
            } else {
                // 确保最终值精确
                setDisplayValue(value);
            }
        };
        // 仅在值变化时启动动画
        if (value !== prevValue.current) {
            animationFrameId.current = requestAnimationFrame(animate);
        }
        // 清理函数
        return () => {
            if (animationFrameId.current) {
                cancelAnimationFrame(animationFrameId.current);
            }
        };
    }, [value, duration]);
    // 应用自定义格式化
    const formattedValue = formatter(displayValue);
    return <span className={className}>{formattedValue}</span>;
};
export default AnimatedNumber;
